package com.tz.advice;


import com.tz.util.HiberanteUtil;
import com.tz.util.MyThreadLocal;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.springframework.stereotype.Component;

/**
 * 自定义 事务 Around advice 类
 * 负责将dao中频繁出现的 事务控制 try-catch-finally 代码抽出
 */
@Component
@Aspect
public class MyTxAdvice {

    private SessionFactory sessionFactory = HiberanteUtil.getSessionFactory();

    @Around("execution(public * com.tz.dao.UserDaoImpl.*(..))")
    Object around(ProceedingJoinPoint pjp) {
        Object result = null;

        Session session = sessionFactory.openSession();
        System.out.println("开启连接...");
        Transaction tx = null;
        try{
            tx = session.beginTransaction();
            System.out.println("开启事务...");
            MyThreadLocal.set(session);
            System.out.println("将session存入线程变量...");
            //接收返回值,相当于箭头3
            result = pjp.proceed();//放行请求,相当于箭头2
            tx.commit();
            System.out.println("提交事务...");
        } catch (Throwable throwable) {
            if(tx != null){
                System.out.println("回滚事务...");
                tx.rollback();
            }
            throwable.printStackTrace();
        } finally {
            System.out.println("关闭连接...");
            session.close();
        }
        return result; //返回值,相当于箭头4
    }

}
